<template>
  <div
    class="ui-rate"
    :class="{ 'is-readonly' : readonly , 'is-disabled' : disabled  }"
    tabindex="0"
    role="radiogroup"
    @touchstart="onTouchStart"
    @touchmove="onTouchMove"
    @touchend="onTouchEnd"
  >
    <div
      class="ui-rate--item"
      ref="items"
      role="radio"
      :style="iconStyle"
      tabindex="0"
      v-for="(item,$index) in list"
      :key="$index"
      :class="{ 'is-disabled' : disabled , 'is-full' : item === 'full' , 'is-half' : item === 'half'}"
    >
      <uiIcon
        class="ui-rate--icon"
        :size="sizeWithUnit"
        :name="item === 'full' ? icon : voidIcon"
        :color="item === 'full' ? color : '#a5a7b2' "
        @click="select($index + 1)"
      />
      <uiIcon
        class="ui-rate--icon ui-rate--icon-half"
        :size="sizeWithUnit"
        :name="item === 'half' ? icon : voidIcon"
        :color="item === 'half' ? color : '#a5a7b2' "
        @click="select($index + 0.5 )"
        v-if="allowHalf && item === 'half'"
      />
    </div>
  </div>
</template>

<script>
import uiIcon from "@/components/base/icon/index";
function getRateStatus(value, index, allowHalf) {
  if (value >= index) {
    return "full";
  }

  if (value + 0.5 >= index && allowHalf) {
    return "half";
  }

  return "void";
}

const MIN_DISTANCE = 10;

function getDirection(x, y) {
  if (x > y && x > MIN_DISTANCE) {
    return "horizontal";
  }

  if (y > x && y > MIN_DISTANCE) {
    return "vertical";
  }

  return "";
}

export default {
  name: "uiRate",
  components: { uiIcon },

  props: {
    size: [Number, String],
    color: {
      type: String,
      default: "#f54305"
    },
    gutter: [Number, String],
    readonly: Boolean,
    disabled: Boolean,
    allowHalf: Boolean,
    voidColor: String,
    iconPrefix: String,
    disabledColor: String,
    value: {
      type: Number,
      default: 0
    },
    icon: {
      type: String,
      default: "ui-icon-star"
    },
    voidIcon: {
      type: String,
      default: "ui-icon-star-o"
    },
    count: {
      type: [Number, String],
      default: 5
    },
    touchable: {
      type: Boolean,
      default: true
    }
  },

  data() {
    return {};
  },

  computed: {
    list() {
      const list = [];
      for (let i = 1; i <= this.count; i++) {
        list.push(getRateStatus(this.value, i, this.allowHalf));
      }

      return list;
    },

    sizeWithUnit() {
      return this.size || 40;
    },

    gutterWithUnit() {
      return this.gutter;
    },

    iconStyle() {
      let style;
      if (this.gutterWithUnit && score !== +count) {
        style = { paddingRight: this.gutterWithUnit };
      }
      return style;
    }
  },

  mounted() {
    // this.bindTouchEvent(this.$el);
  },

  methods: {
    select(index) {
      if (!this.disabled && !this.readonly && index !== this.value) {
        this.$emit("input", index);
        this.$emit("change", index);
      }
    },
    touchStart(event) {
      this.resetTouchStatus();
      this.startX = event.touches[0].clientX;
      this.startY = event.touches[0].clientY;
    },

    touchMove(event) {
      const touch = event.touches[0];
      this.deltaX = touch.clientX - this.startX;
      this.deltaY = touch.clientY - this.startY;
      this.offsetX = Math.abs(this.deltaX);
      this.offsetY = Math.abs(this.deltaY);
      this.direction =
        this.direction || getDirection(this.offsetX, this.offsetY);
    },

    resetTouchStatus() {
      this.direction = "";
      this.deltaX = 0;
      this.deltaY = 0;
      this.offsetX = 0;
      this.offsetY = 0;
    },
    onTouchStart(event) {
      let _this = this;
      if (this.readonly || this.disabled || !this.touchable) {
        return;
      }

      this.touchStart(event);
      // #ifndef APP-NVUE
      uni
        .createSelectorQuery()
        .in(this)
        .selectAll(`.ui-rate--item`)
        .boundingClientRect()
        .exec(ret => {
          const ranges = [];
          ret[0].forEach((rect, index) => {
            if (_this.allowHalf) {
              ranges.push(
                { score: index + 0.5, left: rect.left },
                { score: index + 1, left: rect.left + rect.width / 2 }
              );
            } else {
              ranges.push({ score: index + 1, left: rect.left });
            }
          });

          _this.ranges = ranges;
        });
      // #endif
      // #ifdef APP-NVUE
      dom.getComponentRect(this.$refs["ui-tabs-item"], ret => {
        const ranges = [];

        ret[0].forEach((rect, index) => {
          if (_this.allowHalf) {
            ranges.push(
              { score: index + 0.5, left: rect.left },
              { score: index + 1, left: rect.left + rect.width / 2 }
            );
          } else {
            ranges.push({ score: index + 1, left: rect.left });
          }
        });

        _this.ranges = ranges;
      });
      // #endif
    },

    onTouchMove(event) {
      if (this.readonly || this.disabled || !this.touchable) {
        return;
      }

      this.touchMove(event);

      if (this.direction === "horizontal") {
        const { clientX } = event.touches[0];
        this.select(this.getScoreByPosition(clientX));
      }
    },

    onTouchEnd(event) {
      // if (this.direction === "horizontal") {
      //   const { clientX } = event.touches[0];
      //   this.select(this.getScoreByPosition(clientX));
      // }
    },

    getScoreByPosition(x) {
      for (let i = this.ranges.length - 1; i > 0; i--) {
        if (x > this.ranges[i].left) {
          return this.ranges[i].score;
        }
      }

      return this.allowHalf ? 0.5 : 1;
    }
  }
};
</script>

<style scoped lang="scss" src="./index.scss">
</style>
